using System;
using System.Net.Sockets;
using System.Text;

namespace ChatServer
{
	public class Server
	{
		public Server ()
		{
		}
		public static void ProcessMessage(string message,Socket sock,ref bool islogged,ref int uid)
		{
			message = Ullity.Trim(message);	
			var arr_msg = message.Split(':');
			switch(arr_msg[0])
			{
			case ("login"):
				    if(arr_msg.Length != 3){break;}
					int reftr = TextPackage.Login(arr_msg[1],arr_msg[2]);
					Send("loginstatus:" + (reftr != -1).ToString(),sock);
					if(reftr != -1){
						CGlobalStructure.UserInfo uinfo = new CGlobalStructure.UserInfo(){
							LastPing = Environment.TickCount,
							Sock = sock,
							UserID = reftr,
							UserName = arr_msg[1],
							WailPing = false
							
						};
						islogged = true;						
						uid = reftr;	
						if(MainClass.listconnected.ContainsKey(uid)){
						try{
							Send("showmsg: Bạn thoát ở đây vì đã đăng nhập ở một nơi khác . !" , MainClass.listconnected[uid].Sock);
						}catch{}
						try{
							MainClass.listconnected[uid].Sock.Close();
						}catch{}
						MainClass.listconnected.Remove(uid);
						}
						UserManager.SetUserOnline(uid);
						Send("info:http_avatar="+MainClass.http_avatars +",fullname=" + UserManager.GetFullName(reftr) +
					     ",useravatar=" + UserManager.getAvatar(reftr) +",http_server=" + MainClass.http_server + ",statustext=" + UserManager.GetStatusText(reftr)
					     ,sock);
						string flist =UserManager.GetFrList(uid);
						var lstfriend = Ullity.Split(flist,"|");
						string lstfr = "";
						foreach (String fr in lstfriend){
						if(Ullity.Trim(fr) != ""){
							lstfr += UserManager.getUserInfo(int.Parse(fr)) + ",";
							}
						}
						Ullity.Log(lstfr);
						Send("friendlist:" + lstfr,sock);
						UpdateUserIfo(uid);
						Send("offlinemsg:" + UserManager.GetofflineMSG(uid),sock); 
					    MainClass.listbindding.Remove(sock);
						MainClass.listconnected.Add(reftr,uinfo);					
						MainClass.logOnlineUser();
						}
					break ;	
			case("setstatus"):
				if(arr_msg.Length != 2){break;}
				if(!islogged){sock.Close();return;}
					break;
			case("REPING"):
				if(!islogged){sock.Close();return;}
				var ufo = MainClass.listconnected[uid];
				ufo.LastPing = Environment.TickCount;
				ufo.WailPing = false;
				Ullity.Log("Got replay ping : " + ufo.UserName);
				break;
			case("adduser"):				
				if(arr_msg.Length != 2){break;}
				bool ud = UserManager.adduser(arr_msg[1],uid);
				Send("adduserstatus:" + ud.ToString(),sock);
				String uname = UserManager.GetNameByID(uid);
				if(Ullity.Trim(uname).ToLower()  == Ullity.Trim(arr_msg[1]).ToLower()){break;} 
				if(!UserManager.CheckFriend(uid,UserManager.GetIdByName(arr_msg[1]))){
				SendTo("addfriendnotice: Bạn " + UserManager.GetFullNameByName(uname) + "(" + uname +") muốn thêm bạn vào danh sách bạn bè, bạn có đồng ý không ?:" + uname,uid,UserManager.GetIdByName(arr_msg[1]) ,sock);
			
				}
				if(ud){
					Send("addfriend:" + UserManager.getUserInfo(UserManager.GetIdByName(arr_msg[1])),sock);
				}
				UpdateUserIfo(uid);
				break;
			case("setstatusmessage"):
				if(!islogged){sock.Close();return;}
					break;
			case("getfriendlist"):
				break;
			case("deletefriend"):
				if(!islogged){sock.Close();return;}
				UserManager.deletefriend(uid,arr_msg[1]);
				UpdateIfoOndelete(uid,UserManager.GetIdByName(arr_msg[1]));
				Send("removefriend:" + arr_msg[1],sock);
				break;			
			case ("sendmsg"):
				string msg = Ullity.DecodeString(arr_msg[1]);
				string gname = UserManager.GetNameByID(uid);
				SendTo("sendmsg:" + msg + ":" + gname + ":" + UserManager.GetFullNameByName(gname),uid,UserManager.GetIdByName(arr_msg[2]),sock);
				break;
			case ("<ding>"):
				SendTo("<ding>",uid,UserManager.GetIdByName(arr_msg[2]),sock);
				break;
			case("logout"):
				if(!islogged){sock.Close();return;}
				CGlobalStructure.UserInfo uinfo2 = MainClass.listconnected[uid];
				Ullity.Log("Client " + uinfo2.UserName + " logout . Clear thread and data ",3);
				try{
					UserManager.SetUserOffline(uinfo2.UserID);
					Server.UpdateUserIfo(uinfo2.UserID);
					uinfo2.Sock.Close();
				}catch{Ullity.Log("Close socket failed " + uinfo2.UserName,2);}
				MainClass.listconnected.Remove(uid);						   
				MainClass.logOnlineUser();
				break;
			case("quit"):
				if(!islogged){sock.Close();return;}
				CGlobalStructure.UserInfo uinfo1 = MainClass.listconnected[uid];
				Ullity.Log("Client " + uinfo1.UserName + " quit . Clear thread and data ",3);
				try{
					UserManager.SetUserOffline(uinfo1.UserID);
					Server.UpdateUserIfo(uinfo1.UserID);
					uinfo1.Sock.Close();
				}catch{Ullity.Log("Close socket failed " + uinfo1.UserName,2);}
				MainClass.listconnected.Remove(uid);						   
				MainClass.logOnlineUser();
				break;
			case("getoption"):
				break;
			}
			Ullity.Log(message);
		}
		public static void UpdateUserIfo(int uid)
		{
			string flist =UserManager.GetFrList(uid);
			var lstfriend = Ullity.Split(flist,"|");
			string lstfr = "";
			foreach (String fr in lstfriend){
				if(Ullity.Trim(fr) != ""){
					if(MainClass.listconnected.ContainsKey(int.Parse(fr))){
						var usf = MainClass.listconnected[int.Parse(fr)];
						string stsrs = "updateuser:" + UserManager.getUserInfo(uid);
						Send(stsrs,usf.Sock);
						Ullity.Log(" send status affter delete :" + stsrs + " to " + usf.UserName,3);
					}
					lstfr += UserManager.getUserInfo(int.Parse(fr)) + ",";
				}
			}
		}
		public static void UpdateIfoOndelete(int uid,int fr)
		{

					if(MainClass.listconnected.ContainsKey(fr)){
						var usf = MainClass.listconnected[fr];
						string stsrs = "updateuser:" + UserManager.getUserInfoOff(uid);
						Send(stsrs,usf.Sock);
						Ullity.Log("Send status:" + stsrs + " to " + usf.UserName,3);
					}
					
				

		}
		public static void SendTo(String text,int uid, int toid, Socket Sock){
			if(MainClass.listconnected.ContainsKey(toid)){
				try{
					CGlobalStructure.UserInfo uif = MainClass.listconnected[toid];
					uif.Sock.Send(Encoding.UTF8.GetBytes(text + "\n"));
				}catch(Exception ex){
					UserManager.CreateOfflineMSG(Ullity.EncodeString(text),uid,toid);
					Ullity.Log("sendto err " + ex.Message ,1);
				}
			}else{UserManager.CreateOfflineMSG(Ullity.EncodeString(text),uid,toid);}
		}
		public static void Send(String text,Socket sock){
			sock.Send(Encoding.UTF8.GetBytes(text + "\n"));
		}

	}
}

